%error-verbose

%{
#include "eetc.h"

#if 0
declaration
	: declaration_specifiers ';' { printf("declaration\n"); }

declaration_specifiers
	: storage_class_specifier
	| storage_class_specifier declaration_specifiers
	| struct_or_union_specifier
	;
storage_class_specifier
	: TYPEDEF { printf("typedef\n"); }
	;

type_qualifier
	: CONST
 	;
 
declarator
	: pointer direct_declarator
	| direct_declarator
	;

direct_declarator
	: IDENTIFIER
	| direct_declarator '[' CONSTANT ']'
	;

pointer
	: '*'
	| '*' type_qualifier_list
	| '*' pointer
	| '*' type_qualifier_list pointer
	;

type_qualifier_list
	: type_qualifier
	| type_qualifier_list type_qualifier
	;

type_specifier
	: VOID
	| CHAR
	| INT
	| LONG
	| FLOAT
	| DOUBLE
	| SIGNED
	| UNSIGNED
	| struct_or_union_specifier
	| TYPE_NAME
 	;
 
 struct_or_union_specifier
@@ -81,30 +90,27 @@
 	;
 
 struct_declaration
	: specifier_qualifier_list struct_declarator_list ';'
 	;
 
specifier_qualifier_list
	: type_specifier specifier_qualifier_list
	| type_specifier
	| type_qualifier specifier_qualifier_list
	| type_qualifier


struct_declarator_list
	: struct_declarator
	| struct_declarator_list ',' struct_declarator
	;

struct_declarator
	: declarator
	;

#endif

%}

%union {
	Eetc_Member member;
	Eetc_Declarator declarator;
	int type;
	int i;
	char *s;
}

%token TYPEDEF
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOID
%token STRUCT UNION
%token TYPE_NAME
%token <s> IDENTIFIER
%token <i> CONSTANT

%type <type> type_specifier
%type <declarator> direct_declarator

%%

declaration_list
	: declaration_specifiers
	| declaration_list declaration_specifiers
	;

declaration_specifiers
	: TYPEDEF struct_or_union_specifier IDENTIFIER ';'
	{
		Eetc_Type *type;

		type = calloc(1, sizeof(Eetc_Type));
		type->name = $3;
		//type->dscriptor = $2;

		printf("registering %s\n", type->name);
		eina_hash_add(types, type->name, type);
	}
	| struct_or_union_specifier ';'
		{
			/* get the new eed and add it to the
			 * list of  descriptors
			 */
		}
	;

type_specifier
	: CHAR '*' { $$ = EET_T_STRING; }
	| CHAR 	{ $$ = EET_T_CHAR; }
	| SHORT { $$ = EET_T_SHORT; }
	| INT { $$ = EET_T_INT; }
	| LONG LONG { $$ = EET_T_LONG_LONG; }
	| FLOAT { $$ = EET_T_FLOAT; }
	| DOUBLE { $$ = EET_T_DOUBLE; }
	| UNSIGNED CHAR { $$ = EET_T_UCHAR; }
	| UNSIGNED SHORT { $$ = EET_T_USHORT; }
	| UNSIGNED INT { $$ = EET_T_UINT; }
	| UNSIGNED LONG LONG { $$ = EET_T_ULONG_LONG; }
	| IDENTIFIER {
		printf("identifier >>>\n");
		printf("%s", $1); 
		if (!strcmp($1, "Eina_List"))
			$$ = EET_G_LIST;
	}
	/* array */
	/* var array */
	/* list */
	/* hash */
	;

struct_or_union_specifier
	: struct_or_union IDENTIFIER '{' struct_declaration_list '}'
	| struct_or_union '{' struct_declaration_list '}'
	| struct_or_union IDENTIFIER
	;

struct_or_union
	: STRUCT
	| UNION
	;

struct_declaration_list
	: struct_declaration
	| struct_declaration_list struct_declaration
	;

struct_declaration
	: type_specifier direct_declarator ';'
	;

direct_declarator
	: IDENTIFIER
	{
		$$.name = $1;
		$$.count = 0;
	}
	| IDENTIFIER '[' CONSTANT ']'
	{
		$$.name = $1;
		$$.count = $3;
	}
	;

%%

#include <stdio.h>

void yyerror (char *s)
{
	fprintf (stderr, "%s\n", s);
}
